home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource5 / 365_01 / elvrec.c < prev    next >
C/C++ Source or Header  |  1992-04-06  |  4KB  |  198 lines

  1. /* elvrec.c */
  2.  
  3. /* This file contains the file recovery program */
  4.  
  5. /* Author:
  6.  *    Steve Kirkendall
  7.  *    14407 SW Teal Blvd. #C
  8.  *    Beaverton, OR 97005
  9.  *    kirkenda@cs.pdx.edu
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include "config.h"
  15. #include "vi.h"
  16.  
  17. void recover(basename, outname)
  18.     char    *basename;    /* the name of the file to recover */
  19.     char    *outname;    /* the name of the file to write to */
  20. {
  21.     char    pathname[500];    /* full pathname of the file to recover */
  22.     char    line[600];    /* a line from the /usr/preserve/Index file */
  23.     int    ch;        /* a character from the text being recovered */
  24.     FILE    *from;        /* the /usr/preserve file, or /usr/preserve/Index */
  25.     FILE    *to;        /* the user's text file */
  26.     char    *ptr;
  27. #if OSK
  28.     int        uid;
  29. #endif
  30.  
  31.     /* convert basename to a full pathname */
  32.     if (basename)
  33.     {
  34. #ifndef CRUNCH
  35. # if MSDOS || TOS
  36.         if (!basename[0] || basename[1] != ':')
  37. # else
  38.         if (basename[0] != SLASH)
  39. # endif
  40.         {
  41.             ptr = getcwd(pathname, sizeof pathname);
  42.             if (ptr != pathname)
  43.             {
  44.                 strcpy(pathname, ptr);
  45.             }
  46.             ptr = pathname + strlen(pathname);
  47.             *ptr++ = SLASH;
  48.             strcpy(ptr, basename);
  49.         }
  50.         else
  51. #endif
  52.         {
  53.             strcpy(pathname, basename);
  54.         }
  55.     }
  56.  
  57. #if OSK
  58.     uid = getuid();
  59.     if(setuid(0))
  60.         exit(_errmsg(errno, "Can't set uid\n"));
  61. #endif
  62.     /* scan the /usr/preserve/Index file, for the *oldest* unrecovered
  63.      * version of this file.
  64.      */
  65.     from = fopen(PRSVINDEX, "r");
  66.     while (from && fgets(line, sizeof line, from))
  67.     {
  68.         /* strip off the newline from the end of the string */
  69.         line[strlen(line) - 1] = '\0';
  70.  
  71.         /* parse the line into a "preserve" name and a "text" name */
  72.         for (ptr = line; *ptr != ' '; ptr++)
  73.         {
  74.         }
  75.         *ptr++ = '\0';
  76.  
  77.         /* If the "preserve" file is missing, then ignore this line
  78.          * because it describes a file that has already been recovered.
  79.          */
  80.         if (access(line, 0) < 0)
  81.         {
  82.             continue;
  83.         }
  84.  
  85.         /* are we looking for a specific file? */
  86.         if (basename)
  87.         {
  88.             /* quit if we found it */
  89.             if (!strcmp(ptr, pathname))
  90.             {
  91.                 break;
  92.             }
  93.         }
  94.         else
  95.         {
  96.             /* list this file as "available for recovery" */
  97.             puts(ptr);
  98.         }
  99.     }
  100.  
  101.     /* file not found? */
  102.     if (!basename || !from || feof(from))
  103.     {
  104.         if (from != NULL) fclose(from);
  105.         if (basename)
  106.         {
  107.             fprintf(stderr, "%s: no recovered file has that exact name\n", pathname);
  108.         }
  109.         return;
  110.     }
  111.     if (from != NULL) fclose(from);
  112.  
  113.     /* copy the recovered text back into the user's file... */
  114.  
  115.     /* open the /usr/preserve file for reading */
  116.     from = fopen(line, "r");
  117.     if (!from)
  118.     {
  119.         perror(line);
  120.         exit(2);
  121.     }
  122.  
  123. #if ANY_UNIX
  124.     /* Be careful about user-id.  We want to be running under the user's
  125.      * real id when we open/create the user's text file... but we want
  126.      * to be superuser when we delete the /usr/preserve file.  For UNIX,
  127.      * we accomplish this by deleting the /usr/preserve file *now*,
  128.      * when it is open but before we've read it.  Then we revert to the
  129.      * user's real id.
  130.      */
  131.     unlink(line);
  132.     setuid(getuid());
  133. #endif
  134. #if OSK
  135.     setuid(uid);
  136. #endif
  137.  
  138.     if (outname == NULL) return;
  139.  
  140.     /* open the user's file for writing */
  141.     to = fopen(outname, "w");
  142.     if (!to)
  143.     {
  144.         perror(ptr);
  145.         exit(2);
  146.     }
  147.  
  148.     /* copy the text */
  149.     while ((ch = getc(from)) != EOF)
  150.     {
  151.         putc(ch, to);
  152.     }
  153.  
  154. #if !ANY_UNIX
  155. #if OSK
  156.     fclose(from);
  157.     setuid(0);
  158. #endif
  159.     /* delete the /usr/preserve file */
  160.     unlink(line);
  161. #if OSK
  162.     setuid(uid);
  163. #endif
  164. #endif
  165. }
  166.  
  167. main(argc, argv)
  168.     int    argc;
  169.     char    **argv;
  170. {
  171.     /* check arguments */
  172.     if (argc > 3)
  173.     {
  174.         fprintf(stderr, "usage: %s [preserved_file [recovery_file]]\n", argv[0]);
  175.         exit(1);
  176.     }
  177.  
  178.     /* recover the requested file, or list recoverable files */
  179.     if (argc == 3)
  180.     {
  181.         /* recover the file, but write it to a different filename */
  182.         recover (argv[1], argv[2]);
  183.     }
  184.     else if (argc == 2)
  185.     {
  186.         /* recover the file */
  187.         recover(argv[1], argv[1]);
  188.     }
  189.     else
  190.     {
  191.         /* list the recoverable files */
  192.         recover((char *)0, (char *)0);
  193.     }
  194.  
  195.     /* success! */
  196.     exit(0);
  197. }
  198.